/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.javahispano.javacup.tacticas_aceptadas.Goteck;

import java.util.Vector;
import org.javahispano.javacup.modelo.Constantes;
import org.javahispano.javacup.modelo.Posicion;
import org.javahispano.javacup.modelo.SituacionPartido;

/**
 *
 * @author Administrador
 */
public class Balon {
  
    boolean suelo=false;
    double x; //horizontal
    double y;//vertical
    double z;//altura
    double fx;
    double fy;
    double fz;
    boolean cambio=false;
public Balon(){
    x=0;
    y=0;
    z=0;
    fx=0;
    fy=0;
    fz=0;

}
//devuelve mia, rival ,gol,empate o fuera
public String destinoBalon(SituacionPartido sp){
    Balon nBalon=new Balon();
       nBalon.x=this.x;
       nBalon.y=this.y;
       nBalon.z=this.z;
       nBalon.fx=this.fx;
       nBalon.fy=this.fy;
       nBalon.fz=this.fz;
       
       
       int minimoMia=Integer.MAX_VALUE;
       int minimoRival=Integer.MAX_VALUE;
       for (int i=0;i<11;i++){
           int auxMia=this.obtItParaBalon(sp, i, false);
           int auxRival=this.obtItParaBalon(sp, i, true);
           if(minimoMia>auxMia){minimoMia=auxMia;}
           if(minimoRival>auxRival){minimoRival=auxRival;}
       }
       int fuera=this.obtItParaFuera();
       if(fuera<minimoMia&fuera<minimoRival){
           return "fuera";
       }
       else if(minimoMia<minimoRival){return "mia";}
       else if(minimoMia>minimoRival){return "rival";}
       else return "empate";
    




}

public void actualizarPosicion(double px,double py,double pz){
      Balon nBalon=new Balon();
      nBalon=obtValonFuturo(1);
     
       if(nBalon.x!=px||nBalon.y!=py||nBalon.z!=pz){
           cambio=true;
          
       }
       else{
           cambio=false;
                }

      fx=px-x;
    fy=py-y;
    fz=pz-z;
    x=px;
    y=py;
    z=pz;
 
}


 public void moverBalon2() {
        if (!suelo && z == 0 && fz >= 0 && fz < Constantes.G * 3) {//condicion para que se arrastre
            suelo = true;
        }
        if (suelo) {
            x=x+fx;
            y=y+fy;
            
            fx = fx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            fy = fy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
        } else {
            z = redondeaMultiplo(z + fz, Constantes.G);
             x=x+fx;
            y=y+fy;
            fz = redondeaMultiplo(fz - Constantes.G, Constantes.G);
            fx = fx * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            fy = fy * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            if (z == 0) {
                fz = (-fz - Constantes.G) * Constantes.FACTOR_DISMINUCION_ALTURA_BALON_REBOTE;
                fz = redondeaMultiplo(fz, Constantes.G);
                
            }
        }
    }
 public void moverBalon() {
        if (!suelo && z == 0 && fz >= 0 && fz < Constantes.G * 3) {//condicion para que se arrastre
            suelo = true;
        }
        if (suelo) {
             fx = fx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            fy = fy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            x=x+fx;
            y=y+fy;


        } else {
             fz = redondeaMultiplo(fz - Constantes.G, Constantes.G);
            fx = fx * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            fy = fy * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            z = redondeaMultiplo(z + fz, Constantes.G);
             x=x+fx;
            y=y+fy;

            if (z == 0) {
                fz = (-fz - Constantes.G) * Constantes.FACTOR_DISMINUCION_ALTURA_BALON_REBOTE;
                fz = redondeaMultiplo(fz, Constantes.G);

            }
        }
    }
   private double redondeaMultiplo(double valor, double divisor) {
        return Math.round(valor / divisor) * divisor;
    }
   public Balon obtValonFuturo(int nIteraciones){
       Balon nBalon=new Balon();
       nBalon.x=this.x;
       nBalon.y=this.y;
       nBalon.z=this.z;
       nBalon.fx=this.fx;
       nBalon.fy=this.fy;
       nBalon.fz=this.fz;
       
       int aux=0;
       while(aux<nIteraciones){
           nBalon.moverBalon();
           aux++;
       }
       return nBalon;
   }
   public int obtItParaFuera(){
       Balon nBalon=new Balon();
    nBalon.x=this.x;
       nBalon.y=this.y;
       nBalon.z=this.z;
       nBalon.fx=this.fx;
       nBalon.fy=this.fy;
       nBalon.fz=this.fz;
       int cont=0;
       while(Math.abs(nBalon.x)<Constantes.ANCHO_CAMPO_JUEGO&Math.abs(nBalon.y)<Constantes.LARGO_CAMPO/2&cont<250){
                      cont++;
                       nBalon.moverBalon();

       }
       if(cont>250){
           return 10000000;
       }
       return cont;
   }
   public int obtItParaBalon(SituacionPartido sp,int jugador,boolean rival){
   Balon nBalon=new Balon();
    nBalon.x=this.x;
       nBalon.y=this.y;
       nBalon.z=this.z;
       nBalon.fx=this.fx;
       nBalon.fy=this.fy;
       nBalon.fz=this.fz;
   Posicion pBalon=new Posicion(nBalon.x,nBalon.y);
  if(!rival){
   Posicion pJug=sp.misJugadores()[jugador];
   Double velocidad=0.30+0.30*sp.detalleMisJugadores()[jugador].getVelocidad();

   boolean encontrado=false;
   int iteraciones=0;
   while(encontrado==false){
       double distControl=Constantes.DISTANCIA_CONTROL_BALON;
       double alturaControl=Constantes.ALTURA_CONTROL_BALON;
       if(jugador==0){distControl=Constantes.DISTANCIA_CONTROL_BALON_PORTERO;
       alturaControl=Constantes.ALTO_ARCO;}
       if(nBalon.z<=alturaControl&
       pJug.distancia(new Posicion(nBalon.x,nBalon.y))<distControl+velocidad*iteraciones&
               iteraciones>=sp.iteracionesParaRematar()[jugador]){
           encontrado =true;
        }
       else{
           iteraciones++;
           nBalon.moverBalon();
           

       }
   }

return iteraciones;}
  else{
        Posicion pJug=sp.rivales()[jugador];
   Double velocidad=0.30+0.30*sp.detalleJugadoresRivales()[jugador].getVelocidad();

   boolean encontrado=false;
   int iteraciones=0;
   while(encontrado==false){
       double distControl=Constantes.DISTANCIA_CONTROL_BALON;
       double alturaControl=Constantes.ALTURA_CONTROL_BALON;
       if(jugador==TacticaMonsters.PorteroRival){distControl=Constantes.DISTANCIA_CONTROL_BALON_PORTERO;
       alturaControl=Constantes.ALTO_ARCO;}
       if(nBalon.z<=alturaControl&
       pJug.distancia(new Posicion(nBalon.x,nBalon.y))<distControl+velocidad*iteraciones&
               iteraciones>=sp.iteracionesParaRematarRival()[jugador]){
           encontrado =true;
        }
       else{
           iteraciones++;
           nBalon.moverBalon();


       }
   }

return iteraciones;
  }
   }
   public Balon obtBalonSimTiro(double fuerzaJug,double fuerzaLanz,double angVertical,double angDireccion){
      Balon nBalon=new Balon();
    nBalon.x=this.x;
       nBalon.y=this.y;
       nBalon.z=this.z;
       Double vel=(1.20+1.20*fuerzaJug)*fuerzaLanz;
       vel = vel * Math.cos(angVertical);
       nBalon.fx=Math.cos(angDireccion) * vel;
       nBalon.fy=Math.sin(angDireccion) * vel;
       nBalon.fz=redondeaMultiplo(vel * Math.sin(angVertical), Constantes.G);
  return nBalon;
}
   public double obtDistPase(double fuerzaJug,double fuerzaLanz,double angVertical){
      Balon nBalon=obtBalonSimTiro( fuerzaJug, fuerzaLanz, Math.toRadians(angVertical), 0);
      Posicion pBal=new Posicion(this.x,this.y);
      boolean aire=false;
      boolean encontrado=false;
      double distancia=-1;
      int intentos=0;
      while(encontrado==false&intentos<100){
          if (nBalon.z>Constantes.ALTURA_CONTROL_BALON){aire=true;}
          if(nBalon.z<=Constantes.ALTURA_CONTROL_BALON&&aire){
              distancia=pBal.distancia(new Posicion(nBalon.x,nBalon.y));
              encontrado=true;
          }
          nBalon.moverBalon();//2?
          intentos++;
      }
      return distancia;
   }
    public double obtDistTiro(double fuerzaJug,double fuerzaLanz,double angVertical){
      Balon nBalon=obtBalonSimTiro( fuerzaJug, fuerzaLanz, Math.toRadians(angVertical), 0);
      Posicion pBal=new Posicion(this.x,this.y);
      boolean aire=false;
      boolean encontrado=false;
      double distancia=-1;
      int intentos=0;
      while(encontrado==false&intentos<100){
          if (nBalon.z>Constantes.ALTO_ARCO){aire=true;}
          if(nBalon.z<=Constantes.ALTO_ARCO&&aire){
              distancia=pBal.distancia(new Posicion(nBalon.x,nBalon.y));
              encontrado=true;
          }
          nBalon.moverBalon2();
          intentos++;
      }
      return distancia;
   }

   
}
